package com.joysuch.wwyt.workflow.controller;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.exception.ApiBusinessException;
import com.joysuch.wwyt.workflow.bean.WorkFlowEditModelBean;
import com.joysuch.wwyt.workflow.engine.ProcessAPI;
import com.joysuch.wwyt.workflow.service.WorkFlowProcessService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.ActivitiException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author qingzhou
 * 2020-02-12
 */

@Slf4j
@RestController
@Api(tags = "业务流程-流程配置")
@RequestMapping("/workflow/editor")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ModelEditorController implements ModelDataJsonConstants {

    private final ProcessAPI processAPI;
    private final WorkFlowProcessService workFlowProcessService;


    @GetMapping("/get-model-id")
    public ResultBean getModelId(Long processId) {
        WorkFlowEditModelBean modelBean;
        try {
            modelBean = workFlowProcessService.getProcessModel(processId);
        } catch (ApiBusinessException ex) {
            return ResultBean.fail(ex.getCode(), ex.getMessage());
        }
        return ResultBean.wrapSuccessfulResult(modelBean);
    }


    @GetMapping(value = "/model/{modelId}/json", produces = "application/json")
    public ObjectNode getEditorJson(@PathVariable String modelId) {
        return processAPI.getEditorJson(modelId);
    }


    @ResponseStatus(value = HttpStatus.OK)
    @PutMapping(value = "/model/{modelId}/save")
    public ResultBean saveModel(@PathVariable String modelId,
                                String name,
                                String description,
                                String jsonXml,
                                String svgXml,
                                String modelJson) {
        try {
            WorkFlowEditModelBean modelBean = new WorkFlowEditModelBean();
            modelBean.setModelId(modelId);
            modelBean.setName(name);
            modelBean.setDescription(description);
            modelBean.setJsonXml(jsonXml);
            modelBean.setSvgXml(svgXml);
            modelBean.setModelJson(modelJson);
            String message = processAPI.saveModel(modelBean);
            processAPI.deploy(modelId);
            return ResultBean.success(StringUtils.isNotBlank(message) ? message : Status.SUCCESS.getMsg());
        } catch (ApiBusinessException er) {
            log.error(er.getMessage(), er);
            return ResultBean.fail(er.getCode(), er.getMessage());
        } catch (IOException ie) {
            log.error(ie.getMessage(), ie);
            return ResultBean.fail(Status.PROCESS_DEPLOY_ERROR);
        }
    }


    @GetMapping(value = "/stencilset", produces = "application/json;charset=utf-8")
    public String getStencilset() {
        InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("stencilset.json2");
        try {
            return IOUtils.toString(stencilsetStream, "utf-8");
        } catch (Exception e) {
            throw new ActivitiException("Error while loading stencil set", e);
        }
    }


    @GetMapping("/nodes")
    public Collection<FlowElement> processNodes(String modelId) throws IOException {
        return processAPI.nodes(modelId);
    }


    @GetMapping("/user-task-list")
    public ResultBean userTaskList(String modelId) {
        try {
            List<String> list = processAPI.userTaskList(modelId);
            return ResultBean.wrapSuccessfulResult(list);
        } catch (Exception e) {
            return ResultBean.success(new ArrayList<String>());
        }
    }
}
